Small Example
console.log(x);
x = 5;
var x;
console.log(x);Show output
undefined5
Compiled or interpreted?
This article isn’t about how JS engines work. To understand how hoisting works, let me tell you about the work of the JS engine in a simplified way. First, the code is compiled. The compiler finds and binds all declarations to the corresponding scopes. After that the code is executed
What changes after compilation?
The JS compiler creates variable declarations to the top of their scope for optimization.
JS perceives var x = 5; as two commands. First - declare x, second - assign x the value 5.
So, all variables are declared before any value is assigned to them.
Let’s go back to the example. Try to rewrite the code from the example as it
will look after compilation.
Show answer
var x;
console.log(x); // undefined
x = 5;
console.log(x); // 5What about the functions?
Functions (function declaration) hoisting completely.
testWithDeclaration() // Hoisted
function testWithDeclaration() {
console.log("Hoisted");
}Show code after compilation
function testWithDeclaration() {
console.log("Hoisted");
}
testWithDeclaration() // HoistedBut
testWithExpression(); // TypeError
var testWithExpression = function() {
console.log("Hoisted");
};Show code after compilation
var testWithExpression; // undefined
testWithExpression(); // undefined() - TypeError
var testWithExpression = function() {
console.log("Hoisted");
};testWithArrowFunc(); // TypeError
var testWithArrowFunc = () => console.log("Hoisted");Important
Hoisting is performed at the scope level. So variable declarations hoisting in their own scope and don’t hoisting in another one. Let’s look at an example.
test();
function test() {
console.log(x);
var x = 5;
}Try to rewrite the code from the example as it will look after compilation.
Show answer
function test() {
var x; // x hoisted in test function scope
console.log(x); // undefined
x = 5;
}
test();let & const
JS also hoisting variables declared via let and const,
but doesn’t initialize them with the undefined value, as it happens when using var
console.log(x); // ReferenceError: Cannot access 'x' before initialization
const x = 5;